<?php
/**
 * Date: 2024.8
 * Author: kahn
 */
namespace service\uc\oauth;

class WeixinPublicClient  extends BaseAuthClient
{
    CONST USERINFO_URL = 'https://api.weixin.qq.com/sns/userinfo';
    CONST AUTHORIZE_URL = 'https://open.weixin.qq.com/connect/oauth2/authorize?';
    CONST OAUTH_TOKEN_URL = 'https://api.weixin.qq.com/cgi-bin/token';
    CONST JSTICKET_URL ='https://api.weixin.qq.com/cgi-bin/ticket/getticket';
    CONST TICKET_URL   ="https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=";
    CONST ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token";

    //微信公众号登录
    public function getAuthorizeUrl($callbackUrl)
    {
        $params = array();
        $params['appid'] = $this->config['key'];
        $params['redirect_uri'] = $callbackUrl;
        $params['response_type'] = 'code';
        $params['scope'] = 'snsapi_userinfo';
//        $params['scope'] = 'snsapi_base';
        $params["state"] = "STATE"."#wechat_redirect";
        return self::AUTHORIZE_URL . $this->ToUrlParams($params) ;
    }

    public function getAccessToken($code)
    {
        $params = array(
            'appid' => $this->config['appId'],
            'secret' => $this->config['secret'],
            'code' => $code,
            'grant_type' => 'authorization_code'
        );
        $result = $this->getRequest(self::ACCESS_TOKEN_URL, $params);
        $rawToken = json_decode($result, true);
        \Log::info("getAccessToken info", $rawToken);
        if(isset($rawToken['errcode'])){
            \Log::error("getAccessToken is Error",$rawToken);
            return ['error'=>$rawToken['errcode']];
        }
        return $rawToken;

    }

    public function getJsTicket($access_token){
        $params = array(
            'type'=>'jsapi',
            'access_token'=>$access_token,
        );
        $result = $this->getRequest(self::JSTICKET_URL, $params);
        \Log::info('get wxpublic js_ticket:'.$result);
        $rawToken = array();
        $rawToken = json_decode($result, true);
        if(isset($rawToken['errcode'])&&intval($rawToken['errcode'])>0){
            return ['error'=>$rawToken['errcode'],'errmsg'=>$rawToken['errmsg']];
        }
        return  array(
            'expiredTime' => $rawToken['expires_in'],
            'js_ticket' => $rawToken['ticket'],
        );
    }


    /*获取ticket*/
    public function getTicket($access_token,$params)
    {
        $url = self::TICKET_URL.$access_token;
        $params = json_encode($params);
        $result = $this->postRequest($url,$params);
        \Log::info('get wxpublic ticket:'.$result);
        $rawToken = array();
        $rawToken = json_decode($result, true);
        if(isset($rawToken['errcode'])&&intval($rawToken['errcode'])>0){
            return ['error'=>$rawToken['errcode'],'errmsg'=>$rawToken['errmsg']];
        }
        return  array(
            'expiredTime' => $rawToken['expire_seconds'],
            'ticket' => $rawToken['ticket'],
            'url'    => $url
        );
    }

    /*
     * 生成签名
     *
     * noncestr（随机字符串）, 有效的jsapi_ticket, timestamp（时间戳）, url
     */
    public function makeSign($params){
        ksort($params);
        $string = $this->ToUrlParams($params);
        $string = sha1($string);
        $result = strtoupper($string);
        return $result;
    }

    public function getUserInfo($token)
    {
        $params = array(
            'openid' => $token['openid'] ,
            'access_token' => $token['access_token'],
            'lang' => 'zh_CN');
        $result = $this->getRequest(self::USERINFO_URL, $params);
        \Log::info('wxpublic getUserInfo:', $result);
        $info = json_decode($result, true);
        $userInfo = $this->convertUserInfo($info);
        $userInfo['unionId'] = $token['unionid'];

        return $userInfo;
    }

    private function convertUserInfo ($infos) {
        $userInfo = array();
        $userInfo['nickname'] = $infos['nickname'];
        $userInfo['avatar'] = $infos['headimgurl'];
        return $userInfo;
    }

}